package jfoo.playlist;

import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import javax.swing.JComponent;
import javax.swing.TransferHandler;

import audio.AudioFile;
import audio.AudioFileListTransferable;
import audio.AudioList;
import audio.MP3;

class PlaylistListTransferHandler extends TransferHandler {

	private PlaylistList playlistList;

	PlaylistListTransferHandler(PlaylistList playlistList) {
		this.playlistList = playlistList;
	}


	public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
		if (comp.isEnabled() && (comp instanceof PlaylistList)) {
			for (int i = 0; i < transferFlavors.length; i++) {
				if ((transferFlavors[i].equals(AudioFileListTransferable.AUDIOFILE_LIST_FLAVOR) || (transferFlavors[i]
						.equals(java.awt.datatransfer.DataFlavor.javaFileListFlavor)))
						|| (transferFlavors[i].equals(java.awt.datatransfer.DataFlavor.stringFlavor))) {
					return true;
				}
			}
		}
		
		return false;
	}

	public static void scan(File f, AudioList audioFiles) {
		// System.out.println(f.getAbsolutePath());
		if (f.isDirectory()) {
			File[] liste = f.listFiles();
			for (int i = 0; i < liste.length; i++) {
				scan(liste[i], audioFiles);
			}
		} else {
			if (AudioFile.isAudioFile(f)) {
				try {
					audioFiles.add(new MP3(f));
				} catch (IOException e) {
					System.out.println(f.getPath() + "couldn't be found");

				}
			}
		}
	}

	// public boolean importData(TransferHandler.TransferSupport support) {
	public boolean importData(JComponent comp, Transferable tr) {
		
		playlistList.getDetailsTableTransferHandler().setDropComponent(playlistList);
		
		if (!canImport(comp, tr.getTransferDataFlavors())) {
			return false;
		}
		int insertRow = playlistList.getSelectedIndex();

		// should be used with jre 1.6 with importData(TransferHandler.TransferSupport support) { :
		// JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
		// int index = dl.getRow();

		AudioList audioFiles = new AudioList();
		ArrayList<File> fileList = new ArrayList<File>();
		try {

			if (tr.isDataFlavorSupported(AudioFileListTransferable.AUDIOFILE_LIST_FLAVOR)) {
			//	System.out.println("AudioFileList transferable supported !!!");
				List<AudioFile> list = (List<AudioFile>) tr.getTransferData(AudioFileListTransferable.AUDIOFILE_LIST_FLAVOR);

				playlistList.addToPlaylist(list, insertRow);
				return true;
			}

			// Is it a file list?
			if (tr.isDataFlavorSupported(java.awt.datatransfer.DataFlavor.javaFileListFlavor)) {
				// Get a useful list
				fileList.addAll((List<File>) tr.getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor));
			} // end if: file list
			else // this section will check for a reader flavor.
			{
				// Thanks, Nathan!
				// BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome)
				// support added.
				DataFlavor[] flavors = tr.getTransferDataFlavors();
				boolean handled = false;
				for (int zz = 0; zz < flavors.length; zz++) {
					if (flavors[zz].isRepresentationClassReader()) {

						Reader reader = flavors[zz].getReaderForText(tr);

						BufferedReader br = new BufferedReader(reader);
						fileList = createFileArray(br);
						System.out.println(fileList.toString());
						// Mark that drop is completed.
						// evt.getDropTargetContext().dropComplete(true);

						handled = true;
						break;
						// END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome)
						// support
					} else {
						handled = false;

					}
				}
				if (!handled) { // the source may come from JAVA TODO : fix that
					// dirty way. don't know how
				
					if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) { // Linux
						String urls = (String) tr.getTransferData(DataFlavor.stringFlavor);
						fileList = new ArrayList<File>();
						for (StringTokenizer st = new StringTokenizer(urls, "\r\n"); st.hasMoreTokens();) {
							fileList.add(new File(st.nextToken()));

						}

					}

					handled = true;
				}

				if (!handled) {
					System.out.println("the drag and drop failed, probably due to a flavor thing");
					return false;
				}

			}
		} catch (Exception exc) {
			exc.printStackTrace();
		}

		Iterator<File> iterator = fileList.iterator();

		while (iterator.hasNext()) {
			scan(iterator.next(), audioFiles);
		}
		System.out.println(audioFiles);
		playlistList.addToPlaylist(audioFiles, insertRow);

		// Rectangle rect = detailsTable.getCellRect(index, 0, false);
		// if (rect != null) {
		// detailsTable.scrollRectToVisible(rect);
		// }

		return true;
	}

	private static String ZERO_CHAR_STRING = "" + (char) 0;

	private static ArrayList<File> createFileArray(BufferedReader bReader) {
		try {
			ArrayList<File> list = new ArrayList<File>();
			String line = null;
			while ((line = bReader.readLine()) != null) {
				try {

					// kde seems to append a 0 char to the end of the reader
					if (ZERO_CHAR_STRING.equals(line))
						continue;

					java.io.File file = new java.io.File(new java.net.URI(line));
					// System.out.println(file.getAbsolutePath());
					list.add(file);
				} catch (Exception ex) {

					System.out.println("Error with " + line + ": " + ex.getMessage());
				}
			}

			return list;
		} catch (IOException ex) {
			System.out.println("FileDrop: IOException");
		}
		return new ArrayList<File>();
	}

}